<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2.canvas应用实例之线性小球</title>
</head>
<style>
    canvas {
        display: block;
        margin: 0 auto;
        /* border: 1px solid rgb(0, 0, 0); */
    }
</style>
<body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <script>
        // 获取canvas
        let canvas = document.getElementById('canvas');
        // 获取绘画环境
        let ctx = canvas.getContext('2d');
        // 获取窗口宽高
        // let w = h = 500;
        let w = document.documentElement.clientWidth - 6;
        let h = document.documentElement.clientHeight - 6;
        canvas.width = w;
        canvas.height = h;
        // 定义绘画的类
        function Paint() {
            this.text = ['HTML', "CSS", "Vue", "Javascript", "React", "Less", "TypeScriot", "Java", "GoLang", "C#", "C", "C++", "Node", "Python"];
            // 画线的方法
            this.paintLine = function(x1, y1, x2, y2, color, width) {
                ctx.beginPath();
                ctx.moveTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.strokeStyle = color || '#000';
                ctx.lineWidth = width || '4px';
                ctx.stroke();
                ctx.closePath();
            };
            // 画文字方法
            this.paintText = function(text, x, y, color) {
                ctx.beginPath();
                ctx.font = "20px 微软雅黑";
                ctx.fillStyle = color || '#000';
                ctx.textAlign = "top";
                ctx.textBaseline = "middle";
                ctx.fillText(text, x, y);
            };
            // 画原形方法
            this.paintCircle = function(x, y, r, startDeg, endDeg, color) {
                ctx.beginPath();
                ctx.arc(x, y, r,startDeg, endDeg);
                ctx.fillStyle = color || 'red';
                ctx.fill();
                ctx.closePath();
            };
            // 生成随机颜色的方法
            this.getRandomColor = function () {
                // return '#' + parseInt((Math.random()*0xFFFFFF)).toString(16);
                return `rgb(${Math.floor(paint.getDuringNum(0,255))}, ${Math.floor(paint.getDuringNum(0,255))}, ${Math.floor(paint.getDuringNum(0,255))})`;
             };
             // 生成随机数的方法[10,60]
             this.getDuringNum = function (num1, num2) { 
                 return Math.random()*(num2 - num1) +num1
              }
        };
        let paint = new Paint();
        // 测试方法
        // paint.paintLine(0, 0, 100, 100);
        // paint.paintText("你好", 200, 150);
        // paint.paintCircle(80, 100, 20, 0, Math.PI*2);
        // console.log('随机颜色：', paint.getRandomColor());

        // 小球的类
        class LineCircle {
            constructor (x, y, r, color) {
                this.x = paint.getDuringNum(65, 400);
                this.y = paint.getDuringNum(65, 400);
                this.r = paint.getDuringNum(10, 60);
                this.color = paint.getRandomColor();
                this.speedX = paint.getDuringNum(1,5);
                this.speedY = paint.getDuringNum(1,8);
            };
            // 绘制的方法
            show(i) {
                // 更新小球坐标
                this.updateRun();
                // 画小球
                paint.paintCircle(this.x, this.y, this.r, 0, 2*Math.PI, this.color);
                // 画文字
                paint.paintText(paint.text[i], this.x + this.r, this.y, this.color);
            };
            // 更新小球坐标的方法
            updateRun() {
                // 碰撞检测
                if (this.x - this.r <= 0 || this.x + this.r >= w) {
                    this.speedX = -this.speedX;
                };
                this.x += this.speedX;
                if (this.y - this.r <=0 || this.y + this.r >= h) {
                    this.speedY = -this.speedY;
                };
                this.y += this.speedY;
            }
        };

        // 定义一个存储小球的数组
        let ballArr = [];
        // 循环画多个不一样的小球
        for(let i = 0; i < paint.text.length; i++) {
            let circle = new LineCircle();
            ballArr.push(circle);
            circle.show(i);
            // 画连线
            for(let l =0; l < i; l++) {
                //取出当前小球的前面小球来和当前小球连线
                let preBall = ballArr[l];
                paint.paintLine(circle.x, circle.y, preBall.x, preBall.y, circle.color);
            }   
        };

        // 设置定时器让小球动起来
        setInterval(function() {
            // 清除画布
            ctx.clearRect(0, 0, w, h);
            for(let i =0; i<ballArr.length; i++) {
                ballArr[i].show(i);
                let circle = ballArr[i];
                //  // 画连线
                for(let l =0; l < i; l++) {
                    //取出当前小球的前面小球来和当前小球连线
                    let preBall = ballArr[l];
                    paint.paintLine(circle.x, circle.y, preBall.x, preBall.y, circle.color);
                } 
            }
        }, 20);

    </script>
</body>
</html>